﻿//-----------------------------------------------------------------------
// <copyright file="ApplicationGroup.cs" company="Alan Rodrigues">
//     Copyright (c) Alan Rodrigues. All rights reserved.
// </copyright>
// <developed>Alan Rodrigues (operninha@gmail.com)</developed>
//-----------------------------------------------------------------------

namespace Authorization
{
    using System.Runtime.Serialization;
    using Microsoft.Interop.Security.AzRoles;
    using System.Runtime.InteropServices;

    [DataContract(Name = "ApplicationGroup", Namespace = "http://authorizationservices/v1")]
    public class ApplicationGroup
    {     
        #region Constructors

        protected internal ApplicationGroup(Application application, IAzApplicationGroup2 azmanApplicationGroup, string scopeName)
        { 
            this.AzmanApplicationGroup = azmanApplicationGroup;
            this.Definition = string.IsNullOrEmpty(scopeName) ? Authorization.Definition.Application : Authorization.Definition.Scope;
        }
        protected internal ApplicationGroup(AuthorizationStore store, IAzApplicationGroup2 azmanApplicationGroup)
        {
            this.AzmanApplicationGroup = azmanApplicationGroup;
            this.Definition = Authorization.Definition.AuthorizationStore;
        }

        #endregion

        #region Properties


        /// <summary>
        /// <see cref="ApplicationGroup"/> name.
        /// </summary>
        [DataMember(Name = "Name", IsRequired = true)]
        public string Name { get; set; }

        /// <summary>
        ///  <see cref="ApplicationGroup"/>  description
        /// </summary>
        [DataMember(Name = "Description", IsRequired = false)]
        public string Description
        {
            get;
            set;
        }


        private IAzApplicationGroup2 AzmanApplicationGroup
        {
            get;
            set;
        }


        /// <summary>
        ///  Where this <see cref="ApplicationGroup"/> is definied
        /// </summary>
        [DataMember(Name = "Definition", IsRequired = false)]
        public Definition Definition
        {
            get;
            set;
        }

        #endregion

    #region Methods
        /// <summary>
        /// Adds the specified <see cref="ApplicationGroup"/> object to the list of application groups that belong to this application group.
        /// </summary>
        /// <param name="name">String that contains the Name property of the <see cref="ApplicationGroup"/> object to add to the list of the application groups that belong to this application group.</param>
        public void AddAppMember(string name)
        {
            SecUtility.CheckParameter(ref name, true, true, false, 64, "name");
            this.AzmanApplicationGroup.AddAppMember(name, null);            
        }


        public void DeleteMemberNames(string[] usernames)
        {
            SecUtility.CheckArrayParameter(ref usernames, true, true, false, 64, "usernames");
            foreach (var username in usernames)
            {
                this.AzmanApplicationGroup.DeleteMemberName(username, null);
            }
        }


        public void DeleteMembers(string[] Sid)
        {
            SecUtility.CheckArrayParameter(ref Sid, true, true, false, 64, "Sid");
            foreach (var username in Sid)
            {
                this.AzmanApplicationGroup.DeleteMember(username, null);
            }
        }


        /// <summary>
        /// Removes the specified <see cref="ApplicationGroup"/> object from the list of application groups that belong to this application group.
        /// </summary>
        /// <param name="name">String that contains the Name property of the <see cref="ApplicationGroup"/> object to remove from the list of application groups that belong to this application group.</param>
        public void DeleteAppMember(string name)
        {
            SecUtility.CheckParameter(ref name, true, true, false, 64, "name");
            this.AzmanApplicationGroup.DeleteAppMember(name, null);
        }
        
        /// <summary>
        /// Adds the specified <see cref="ApplicationGroup"/> object to the list of application groups that are refused membership in this application group.
        /// </summary>
        /// <param name="name">String that contains the Name property of the <see cref="ApplicationGroup"/> object to add to the list of the application groups that are refused membership in this application group.</param>
        public void AddAppNonMember(string name)
        {
            SecUtility.CheckParameter(ref name, true, true, false, 64, "name");
            this.AzmanApplicationGroup.AddAppNonMember(name, null);
        }

        /// <summary>
        /// Removes the specified <see cref="ApplicationGroup"/> object from the list of application groups that are refused membership in this application group.
        /// </summary>
        /// <param name="name">String that contains the Name property of the <see cref="ApplicationGroup"/> object to remove from the list of the application groups that are refused membership in this application group.</param>
        public void DeleteAppNonMember(string name)
        {
            SecUtility.CheckParameter(ref name, true, true, false, 64, "name");
            this.AzmanApplicationGroup.DeleteAppNonMember(name, null);
        }
     
        /// <summary>
        /// Adds the specified security identifier (sid) in text form to the list of accounts that belong to the application group.
        /// </summary>
        /// <param name="sid">String that contains the text form of the sid to add to the list of accounts that belong to the application group.</param>
        /// <remarks> (sid) A data structure of variable length that identifies user, group, and computer accounts. Every account on a network is issued a unique sid when the account is first created. Internal processes in Windows refer to an account's sid rather than the account's user or group name. </remarks>
        public void AddMember(string sid)
        {
            SecUtility.CheckParameter(ref sid, true, true, false, 0, "sid");
            this.AzmanApplicationGroup.AddMember(sid, null);
        }


        public void AddMembers(string[] Sids)
        {
            SecUtility.CheckArrayParameter(ref Sids, true, true, false, 64, "Sids");
            foreach (var Sid in Sids)
            {
                this.AzmanApplicationGroup.AddMember(Sid, null);
            }
        }

        public void AddMemberNames(string[] memberNames)
        {
            SecUtility.CheckArrayParameter(ref memberNames, true, true, false, 64, "memberNames");
            foreach (var memberName in memberNames)
            {
                this.AzmanApplicationGroup.AddMemberName(memberName, null);
            }
        }
         

        /// <summary>
        /// Removes the specified sid in text form from the list of accounts that belong to the application group.
        /// </summary>
        /// <param name="sid">String that contains the text form of the sid to remove from the list of accounts that belong to the application group.</param>
        public void DeleteMember(string sid)
        {
            SecUtility.CheckParameter(ref sid, true, true, false, 0, "sid");
           this.AzmanApplicationGroup.DeleteMember(sid, null);
        }
        
        /// <summary>
        /// Adds the specified sid in text form to the list of accounts that are refused membership in the application group
        /// </summary>
        /// <param name="sid">String that contains the text form of the sid to add to the list of accounts that are refused membership in the application group.</param>
        public void AddNonMember(string sid)
        {
            SecUtility.CheckParameter(ref sid, true, true, false, 0, "sid");
            this.AzmanApplicationGroup.AddNonMember(sid, null);
        }

        /// <summary>
        /// Removes the specified sid in text form from the list of accounts that are refused membership in the application group.
        /// </summary>
        /// <param name="sid">String that contains the text form of the sid to remove from the list of accounts that are refused membership in the application group.</param>
        public void DeleteNonMember(string sid)
        {
            SecUtility.CheckParameter(ref sid, true, true, false, 0, "sid");
            this.AzmanApplicationGroup.DeleteNonMember(sid, null);
        }

        /// <summary>
        /// The AddMemberName method adds the specified account name to the list of accounts that belong to the application group.
        /// </summary>
        /// <param name="name">String that contains the account name to add to the list of accounts that belong to the application group. The account name must be in user principal name (UPN) format. The LookupAccountName function is called to retrieve the domain.</param>
        public void AddMemberName(string name)
        {
            SecUtility.CheckParameter(ref name, true, true, false, 0, "name");
            this.AzmanApplicationGroup.AddMemberName(name, null);
        }

        /// <summary>
        /// Removes the specified account name from the list of accounts that belong to the application group.
        /// </summary>
        /// <param name="name">String that contains the account name to remove from the list of accounts that belong to the application group. The account name must be in user principal name (UPN) format (for example, "someone@example.com"). The LookupAccountName function is called to retrieve the domain.</param>
        public void DeleteMemberName(string name)
        {
            SecUtility.CheckParameter(ref name, true, true, false, 0, "name");
            this.AzmanApplicationGroup.DeleteMemberName(name, null);
        }

        /// <summary>
        /// Adds the specified account name to the list of accounts that are refused membership in the application group.
        /// </summary>
        /// <param name="name">String that contains the sid to add to the list of accounts that are refused membership in the application group. The account name must be in user principal name (UPN) format (for example, "someone@example.com"). The LookupAccountName function is called to retrieve the domain.</param>
        public void AddNonMemberName(string name)
        {
            SecUtility.CheckParameter(ref name, true, true, false, 0, "name");
            this.AzmanApplicationGroup.AddNonMemberName(name, null);
        }

        /// <summary>
        /// Removes the specified account name from the list of accounts that are refused membership in the application group.
        /// </summary>
        /// <param name="name">String that contains the sid to add to the list of accounts that are refused membership in the application group. The account name must be in user principal name (UPN) format (for example, "someone@example.com"). The LookupAccountName function is called to retrieve the domain.</param>
        public void DeleteNonMemberName(string name)
        {
            SecUtility.CheckParameter(ref name, true, true, false, 0, "name");
            this.AzmanApplicationGroup.DeleteNonMemberName(name, null);
        }


        public string[] GetMembers()
        {
            return  Util.ObjectToArrayOfString(this.AzmanApplicationGroup.Members);
        }

        public string[] GetMemberNames()
        {
            return Util.ObjectToArrayOfString(this.AzmanApplicationGroup.MembersName);
        }

        public string[] GetNonMembers()
        {
            return Util.ObjectToArrayOfString(this.AzmanApplicationGroup.NonMembers);
        }

        public string[] GetNonMemberNames()
        {
            return Util.ObjectToArrayOfString(this.AzmanApplicationGroup.NonMembersName);
        }

        /// <summary>
        /// Aborts changes made to the <see cref="ApplicationGroup"/> object.
        /// </summary>
        public void Abort()
        {
            if (this.AzmanApplicationGroup != null)
            {
                this.AzmanApplicationGroup.Submit((int)tagAZ_PROP_CONSTANTS.AZ_SUBMIT_FLAG_ABORT, null);
                this.Name = this.AzmanApplicationGroup.Name;
                this.Description = this.AzmanApplicationGroup.Description;
            }
        }

        /// <summary>
        /// Persists changes made to the <see cref="ApplicationGroup"/> object.
        /// </summary>
        public void Save()
        {
            if (this.AzmanApplicationGroup != null)
            {
                this.AzmanApplicationGroup.Name = this.Name;
                this.AzmanApplicationGroup.Description = this.Description;
                this.AzmanApplicationGroup.Submit(0, null);
            }
        }
    #endregion

         #region desconstructors
        ~ApplicationGroup()
        {

            if (AzmanApplicationGroup != null)
                Marshal.FinalReleaseComObject(AzmanApplicationGroup);
        }
        #endregion
    
    }
}
